"""
通用模型适配器
支持任意OpenAI兼容的API接口，用于处理新的或未知的模型提供商
"""

import httpx
import json
from typing import Dict, Any, List, Optional
import logging
from .base_adapter import BaseModelAdapter

logger = logging.getLogger(__name__)


class GenericAdapter(BaseModelAdapter):
    """通用模型适配器，支持任意OpenAI兼容的API"""

    def __init__(self, api_key: str, api_url: str, model: str, provider_name: str = "Generic"):
        super().__init__(api_key, api_url, model)
        self.provider_name = provider_name
        self.supports_json_format = None  # 动态检测是否支持JSON格式

    async def generate_completion(
        self,
        messages: List[Dict[str, str]],
        temperature: float = 0.2,
        max_tokens: int = 4000,
        timeout: float = 300.0,
        **kwargs
    ) -> str:
        """生成文本完成"""
        try:
            # 构建基础请求数据
            request_data = {
                "model": self.model,
                "messages": messages,
                "temperature": temperature,
                "max_tokens": max_tokens,
                **kwargs
            }

            # 如果还没有检测过JSON格式支持，先尝试使用JSON格式
            if self.supports_json_format is None:
                request_data["response_format"] = {"type": "json_object"}
                logger.info(f"首次调用 {self.provider_name}/{self.model}，尝试使用JSON格式")

            async with httpx.AsyncClient(timeout=timeout) as client:
                response = await client.post(
                    self.api_url,
                    headers=self._get_headers(),
                    json=request_data
                )

                # 处理响应
                if response.status_code != 200:
                    error_detail = await self._parse_error_response(response)
                    
                    # 检查是否是JSON格式不支持的错误
                    if self._is_json_format_error(error_detail) and self.supports_json_format is None:
                        logger.warning(f"{self.provider_name}/{self.model} 不支持JSON格式，重试不使用JSON格式")
                        self.supports_json_format = False
                        
                        # 移除JSON格式要求重试
                        request_data.pop("response_format", None)
                        response = await client.post(
                            self.api_url,
                            headers=self._get_headers(),
                            json=request_data
                        )
                        
                        if response.status_code == 200:
                            result = response.json()
                            if self._validate_response_format(result):
                                content = result["choices"][0]["message"]["content"]
                                logger.info(f"{self.provider_name} API调用成功（无JSON格式），返回内容长度: {len(content)}")
                                return content
                    
                    raise Exception(f"API调用失败: 状态码={response.status_code}, 错误详情: {error_detail}")

                # 标记JSON格式支持状态
                if self.supports_json_format is None:
                    self.supports_json_format = True
                    logger.info(f"{self.provider_name}/{self.model} 支持JSON格式")

                result = response.json()

                # 验证响应格式
                if not self._validate_response_format(result):
                    raise Exception("API返回格式异常：缺少必要字段")

                content = result["choices"][0]["message"]["content"]
                logger.info(f"{self.provider_name} API调用成功，返回内容长度: {len(content)}")
                return content

        except Exception as e:
            logger.error(f"{self.provider_name} API调用失败: {str(e)}")
            raise

    def _get_headers(self) -> Dict[str, str]:
        """获取请求头"""
        return {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }

    async def _parse_error_response(self, response: httpx.Response) -> str:
        """解析错误响应"""
        try:
            error_response = response.json()
            return str(error_response)
        except:
            return response.text[:200] if response.text else "未知错误"

    def _is_json_format_error(self, error_detail: str) -> bool:
        """检查是否是JSON格式不支持的错误"""
        json_error_keywords = [
            "response_format",
            "json_object",
            "json format",
            "not supported",
            "invalid parameter"
        ]
        error_lower = error_detail.lower()
        return any(keyword in error_lower for keyword in json_error_keywords)

    def _validate_response_format(self, result: Dict[str, Any]) -> bool:
        """验证响应格式是否正确"""
        try:
            if "choices" not in result or not result["choices"]:
                return False

            choice = result["choices"][0]
            if "message" not in choice:
                return False

            message = choice["message"]
            if "content" not in message:
                return False

            return True
        except (KeyError, IndexError, TypeError):
            return False

    def get_provider_name(self) -> str:
        """获取提供商名称"""
        return self.provider_name

    def get_supported_models(self) -> List[str]:
        """获取支持的模型列表"""
        # 通用适配器支持任意模型名称
        return [self.model] if self.model else []

    def validate_config(self) -> bool:
        """验证配置是否有效"""
        if not self.api_key or self.api_key.strip() == "":
            logger.error(f"{self.provider_name} API密钥未配置")
            return False

        if not self.api_url or self.api_url.strip() == "":
            logger.error(f"{self.provider_name} API地址未配置")
            return False

        if not self.model or self.model.strip() == "":
            logger.error(f"{self.provider_name} 模型名称未配置")
            return False

        # 检查是否为占位符
        placeholder_keys = [
            "your-api-key-here",
            "your-custom-api-key-here",
            "sk-xxxxxxxxxxxxxxxx"
        ]
        if self.api_key in placeholder_keys:
            logger.error(f"检测到 {self.provider_name} API密钥为占位符，请配置真实的API密钥")
            return False

        # 检查URL格式
        if not (self.api_url.startswith("http://") or self.api_url.startswith("https://")):
            logger.error(f"{self.provider_name} API地址格式不正确，必须以http://或https://开头")
            return False

        return True

    def get_model_info(self) -> Dict[str, Any]:
        """获取模型信息"""
        return {
            "provider": self.provider_name,
            "model": self.model,
            "api_url": self.api_url,
            "supports_json_format": self.supports_json_format,
            "is_generic": True
        }
